package com.zframeworks.core.util;


import com.zframeworks.core.z;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日期工具类
 * @author 4223947@qq.com
 *
 */
public class DateUtil {

	public static void main(String[] args) throws ParseException {

		//String s = getDateTime();
		String s = "2023-01-30";
		boolean d = isDate(s);
		System.out.println(s+" "+d);

//		String now_time = "2023-09-23 12:29:42";
//		String start_time = "2023-09-22 12:29:42";
//		String end_time = "2023-09-23 12:29:43";

		//System.out.println(isValidTime(now_time,start_time,end_time));
	}

	/**
	 * 判读【当前时间】是否在【开始时间】与【结束时间】之间
	 * 参数时间必须为 yyyy-MM-dd HH:mm:ss
	 * @param now_time 当前时间
	 * @param start_time 开始时间
	 * @param end_time 结束时间
	 * @return
	 */
	public static boolean isValidTime(String now_time,String start_time,String end_time){
		//判读三个参数不可为空
		if(z.isNotNull(now_time) && z.isNotNull(start_time) && z.isNotNull(end_time)){
			//判读三个参数都是日期字符串
			if(isDate(now_time) && isDate(start_time) && isDate(end_time)){
				//将时间转为 LocalDateTime 类型
				LocalDateTime now =LocalDateTime.parse(now_time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
				LocalDateTime start =LocalDateTime.parse(start_time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
				LocalDateTime end =LocalDateTime.parse(end_time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
				if (now.isAfter(start) && now.isBefore(end)) {
					//在区间里
					return true;
				}else{
					//不在区间里
					return false;
				}
			}else{
				return false;
			}
		}else{
			return false;
		}
	}

	/**
	 * 计算时间差[秒]
	 * @param start_time
	 * @param end_time
	 * @return
	 */
	public static int CalcTimeDifference(String start_time,String end_time) {
		int times = 0;
		if(z.isNotNull(start_time) && z.isNotNull(end_time)) {
			Date std = StringToDate(start_time,"");
			long st = std.getTime();

			Date etd = StringToDate(end_time,"");
			long et = etd.getTime();

			BigDecimal times_big = (new BigDecimal(et).subtract(new BigDecimal(st))).divide(new BigDecimal(1000),4, BigDecimal.ROUND_DOWN);

			if(times_big.intValue()>=0) {
				times = times_big.intValue();
			}else{
				times = -1;
			}
		}
		return times;

	}




	/**
	 * 根据出生日期计算年龄
	 * @param birthday
	 * @return
	 */
	public static int getAge(String birthday) {
		return getAge(StringToDate(birthday,"yyyy-MM-dd"));
	}

	/**
	 * 根据出生日期计算年龄
	 * @param birthday
	 * @return
	 */
	public static int getAge(Date birthday) {
		/*从Calendar对象中或得一个Date对象*/
		Calendar cal = Calendar.getInstance();
		/*把出生日期放入Calendar类型的bir对象中，进行Calendar和Date类型进行转换*/
		Calendar bir = Calendar.getInstance();
		bir.setTime(birthday);
		/*取出当前年月日*/
		int yearNow = cal.get(Calendar.YEAR);
		int monthNow = cal.get(Calendar.MONTH);
		int dayNow = cal.get(Calendar.DAY_OF_MONTH);

		/*取出出生年月日*/
		int yearBirth = bir.get(Calendar.YEAR);
		int monthBirth = bir.get(Calendar.MONTH);
		int dayBirth = bir.get(Calendar.DAY_OF_MONTH);
		/*大概年龄是当前年减去出生年*/
		int age = yearNow - yearBirth;
		/*如果出当前月小与出生月，或者当前月等于出生月但是当前日小于出生日，那么年龄age就减一岁*/
		if(monthNow < monthBirth || (monthNow == monthBirth && dayNow < dayBirth)){
			age--;
		}
		if(age<0){
			return 0;
		}else{
			return age;
		}
	}


	/**
	 * 获取日期
	 */
	public static String getDate() {
		return getDateTime("yyyy-MM-dd");
	}

	/**
	 * 获取日期时间
	 */
	public static String getDateTime() {
		return getDateTime("yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 获取日期时间
	 */
	public static String getTime() {
		return getDateTime("HH:mm:ss");
	}

	/**
	 * 文本日期时间格式化
	 * @param date
	 * @param date_pattern
	 * @param new_pattern
	 * @return
	 */
	public static String FormatStringDate(String date, String date_pattern,String new_pattern) {
		String rdate = "";
		if(z.isNotNull(date)) {
			if(z.isNotNull(date_pattern)) {
				if(z.isNotNull(new_pattern)) {
					try {
						DateTimeFormatter formatter = DateTimeFormatter.ofPattern(date_pattern);
						LocalDateTime dateTime = LocalDateTime.parse(date, formatter);
						rdate = dateTime.format(DateTimeFormatter.ofPattern(new_pattern));

					} catch (Exception e) {
						z.Error("FormatStringDate Error|日期数据格式化出错", e);
					}

				}

			}

		}


		return rdate;
	}

	/**
	 * 日期格式化
	 *
	 * @param date
	 * @param pattern
	 *            yyyy-MM-dd yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String FormatDate(Object date, String pattern) {
		if(date!=null && date instanceof Date) {
			SimpleDateFormat dateformat1 = new SimpleDateFormat(pattern);
			return dateformat1.format(date);
		}else {
			return String.valueOf(date);
		}

	}

	/**
	 * 将字符串转换为时间
	 * @param strDate
	 * @param pattern
	 * @return
	 */
	public static Date StringToDate(String strDate,String pattern) {
		if(z.isNull(pattern)) {
			pattern = "yyyy-MM-dd HH:mm:ss";
		}
		SimpleDateFormat formatter = new SimpleDateFormat(pattern);
		ParsePosition pos = new ParsePosition(0);
		Date strtodate = formatter.parse(strDate, pos);
		return strtodate;
	}

	/**
	 * 将日期转为字符串
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String DateToString(Date date,String pattern) {
		if(z.isNull(pattern)) {
			pattern = "yyyy-MM-dd HH:mm:ss";
		}
		SimpleDateFormat formatter = new SimpleDateFormat(pattern);
		String dateString = formatter.format(date);
		return dateString;
	}

	/**
	 * 获取日期
	 * @param pattern yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static String getDateTime(String pattern) {
		LocalDateTime now = LocalDateTime.now();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
		return now.format(formatter);
	}

	/**
	 * 获取日期-英文
	 * @param pattern "MMM yyyy"
	 * @param locale Locale.UK
	 * @return
	 * getDateTime("MMM yyyy",Locale.UK) 返回 "Mar 2021"
	 */
	public static String getDateTime(String pattern,Locale locale) {
		SimpleDateFormat dateformat1 = new SimpleDateFormat(pattern,locale);
		return dateformat1.format(new Date());
	}

	/**
	 *
	 * @Title: addDays
	 * @Description: TODO("当前日期后的多少天")
	 * @param @param date
	 * @param @param days
	 * @param @return 设定文件
	 * @return String 返回类型
	 * @throws
	 */
	public static String addYear(String date, int year) {
		return DateAdd(date,"yyyy-MM-dd",Calendar.YEAR,year,null);
	}

	/**
	 * 日期时间加N
	 * @param calendar 加N的类型年、月、日、小时、分
	 * @param n 数量
	 * @return
	 */
	public static String DateAdd(int calendar,int n) {
		return DateAdd(null,null,calendar,n,null);
	}

	/**
	 * 日期时间加N
	 * @param date 日期时间 如果为空默认为当前时间
	 * @param date_pattern 日期时间的标准格式，如果date为空，date_pattern默认为yyyy-MM-dd HH:mm:ss
	 * @param calendar 加N的类型，年、月、日、小时、分
	 * @param result_date_pattern 返回日期的格式，如果为空，默认为date_pattern格式
	 * @return
	 */
	public static String DateAdd(String date,String date_pattern,int calendar,int n,String result_date_pattern) {
		String rdate = "";
		try {
			if(z.isNull(date)) {
				date = getDateTime();
				date_pattern = "yyyy-MM-dd HH:mm:ss";
			}else {
				if(z.isNull(date_pattern)) {
					z.exception("输入的日期时间未定义格式|date_pattern is not null");
				}
			}
			SimpleDateFormat sdf = new SimpleDateFormat(date_pattern);
			Calendar cd = Calendar.getInstance();
			cd.setTime(sdf.parse(date));
			//日期时间加N，calendar为类型，取Calendar类的成员变量
			cd.add(calendar, n);

			//如果result_date_pattern为空
			if(z.isNull(result_date_pattern)) {
				result_date_pattern = date_pattern;
			}
			rdate = sdf.format(cd.getTime());
			//判读是否有返回格式
			if(z.isNotNull(result_date_pattern) && z.isNotNull(rdate)) {
				//格式化返回值
				SimpleDateFormat rdateformat = new SimpleDateFormat(date_pattern);
				rdate = DateToString(rdateformat.parse(rdate), result_date_pattern);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return rdate;
	}




	/**
	 * 判断字符串是否为日期格式
	 * @param strDate
	 * @return
	 */
	public static boolean isDate(String strDate) {
		boolean b = false;
		try {
			if(strDate.length() == 19 ){
				LocalDateTime.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
			}else if(strDate.length() == 10){
				LocalDate.parse(strDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
			}
			b = true;
		} catch (DateTimeParseException e) {
		}
		return b;
	}
	

}
